﻿using System;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.Xml;
using System.Text.RegularExpressions;


namespace SimpleRedisClinet
{
    /// <summary>
    /// simple redis client class
    /// yangmeng(hvbird@gmail.com)
    /// 2011-01-20
    /// </summary>
    public class RedisSet : RedisBase
    {
        public RedisSet(string hostip, int port)
            : base(hostip,port)
        {
            
        }

        public bool AddMember<T>(string key, T obj)
        {
            check_key(key);

            System.Text.StringBuilder sb = new StringBuilder();
            sb.Append("SADD ");
            sb.Append(key);
            sb.Append(" ");

            string strvalue = get_serializer_str<T>(obj);
            sb.Append(System.Text.Encoding.UTF8.GetByteCount(strvalue));
            sb.Append("\r\n");
            sb.Append(strvalue);
            sb.Append("\r\n");


            ResponseClass ret = send_and_receive(sb.ToString());

            if (ret.Number > 0)
                return true;

            return false;
        }

        public bool HasMember<T>(string key, T obj)
        {
            // not exists or data type error
            if (GetDataType(key) != RedisDataType.Set)
                return false;

            System.Text.StringBuilder sb = new StringBuilder();
            sb.Append("SISMEMBER " + key + " ");

            string strvalue = get_serializer_str<T>(obj);
            sb.Append(System.Text.Encoding.UTF8.GetByteCount(strvalue));
            sb.Append("\r\n");
            sb.Append(strvalue);
            sb.Append("\r\n");

            ResponseClass ret = send_and_receive(sb.ToString());

            if (ret.Number > 0)
                return true;

            return false;
        }

        public bool Remove<T>(string key, T obj)
        {
            // not exists or data type error
            if (GetDataType(key) != RedisDataType.Set)
                return false;

            System.Text.StringBuilder sb = new StringBuilder();
            sb.Append("SREM " + key + " ");

            string strvalue = get_serializer_str<T>(obj);
            sb.Append(System.Text.Encoding.UTF8.GetByteCount(strvalue));
            sb.Append("\r\n");
            sb.Append(strvalue);
            sb.Append("\r\n");

            ResponseClass ret = send_and_receive(sb.ToString());

            if (ret.Number > 0)
                return true;

            return false;
        }

        public T PopRandItem<T>(string key)
        {
            // not exists or data type error
            if (GetDataType(key) != RedisDataType.Set)
                return default(T);

            string cmdstr = "SPOP " + key + "\r\n";

            ResponseClass ret = send_and_receive(cmdstr);

            if (ret.Strings.Count > 0)
            {
                T retobj = get_deserialized_obj<T>(ret.Strings[0]);
                return retobj;
            }

            return default(T);
        }


        public int GetItemCount(string key)
        {
            check_key(key);

            // not exists or data type error
            if (GetDataType(key) != RedisDataType.Set)
                return 0;

            string cmdstr = "SCARD " + key + "\r\n";

            ResponseClass ret = send_and_receive(cmdstr);

            return ret.Number;
        }
    }
}
